package qc.module.ehs.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import qc.common.core.constants.QCConstant;
import qc.common.core.enums.*;
import qc.common.core.exception.QCPromptException;
import qc.common.core.unify.QCUnifyReturnValue;
import qc.common.core.utils.DateUtil;
import qc.common.core.utils.IdentifierUtil;
import qc.module.ehs.dto.check.CheckTableDto;
import qc.module.ehs.dto.task.*;
import qc.module.ehs.dto.taskconsole.TaskConsoleQueryConditionDto;
import qc.module.ehs.dto.taskconsole.TaskConsoleUnitTaskItemPaginationQueryConditionDto;
import qc.module.ehs.dto.taskgroup.TaskGroupAddDto;
import qc.module.ehs.dto.taskgroup.TaskGroupInfoDto;
import qc.module.ehs.dto.taskgroup.TaskGroupItemsDto;
import qc.module.ehs.dto.taskitem.TaskItemInfoDto;
import qc.module.ehs.dto.taskitem.TaskItemPaginationQueryResultDto;
import qc.module.ehs.dto.unit.EhsUnitDto;
import qc.module.ehs.entity.EhsTaskInfo;
import qc.module.ehs.entity.EhsTaskItem;
import qc.module.ehs.mapper.EhsTaskInfoMapper;
import qc.module.ehs.repository.EhsTaskInfoRepository;
import qc.module.ehs.repository.EhsTaskItemRepository;
import qc.module.platform.dto.uac.UacUserInfoDto;

import java.util.*;
import java.util.stream.Collectors;

/**
 * EhsTaskInfoService
 * 任务信息service
 *
 * @author QuCheng Tech
 * @since 2024/11/13
 */
@Service
public class EhsTaskInfoService {

    @Autowired
    private EhsTaskInfoRepository taskInfoRepository;

    @Autowired
    private EhsTaskItemRepository taskItemRepository;

    @Autowired
    private EhsTaskGroupService taskGroupService;

    @Autowired
    private EhsTaskItemService taskItemService;

    @Autowired
    private EhsUnitInfoService unitInfoService;

    @Autowired
    private EhsCheckTableService checkTableService;

    /**
     * 获取安全任务信息
     *
     * @param id 任务ID
     * @return TaskInfoDto
     * @author QuCheng Tech
     * @since 2024/11/13
     */
    public TaskInfoDto getTaskInfo(String id) {

        EhsTaskInfo en = taskInfoRepository.selectById(id);
        if (Objects.nonNull(en)) {
            return EhsTaskInfoMapper.MAPPER.entityToDto(en);
        }
        return null;
    }

    /**
     * 新建安全任务
     *
     * @param addDto 新建对象DTO
     * @return 成功返回任务ID，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/13
     */
    public String add(TaskAddOrEditDto addDto, UacUserInfoDto userInfo) throws QCPromptException {
        //验证dto并将其转换为Entity
        EhsTaskInfo en = null;
        try {
            en = validateAndConvertDtoToEntity(addDto);
        } catch (QCPromptException e) {
            return e.getMessage();
        }

        //调用一次预览结果，判断结果是否通过验证
        TaskPreviewResultDto previewResult = getPreviewResult(en, addDto.getChecktableids(), addDto.getGroupobjids());
        if (previewResult.isIsok() == false)
            return "验证任务信息未通过，" + previewResult.getMsg();

        //生成任务ID
        en.setTaskid(IdentifierUtil.randomUUID());
        //新增时，对任务的添加人ID和名称进行赋值
        if (userInfo != null) {
            en.setInuserid(userInfo.getId());
            en.setInusername(userInfo.getName());
        }

        //3.新增数据
        if (taskInfoRepository.insert(en) < 0x1) {
            return QCUnifyReturnValue.Warn("新建安全任务失败");
        }

        //dto中的“任务分组对象ID集合”不为空，则设置任务分组
        if (addDto.getGroupobjids() != null && addDto.getGroupobjids().length > 0x0) {
            TaskSetGroupObjectsDto setGroupDto = new TaskSetGroupObjectsDto();
            setGroupDto.setTaskid(en.getTaskid());
            setGroupDto.setGroupobjtype(en.getGroupobjtype().getIndex());
            setGroupDto.setGroupobjids(addDto.getGroupobjids());
            setTaskGroups(setGroupDto);
        }

        return QCUnifyReturnValue.Success();
    }

    /**
     * 修改安全任务
     *
     * @param editDto 修改对象DTO
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/14
     */
    public String update(TaskAddOrEditDto editDto) throws QCPromptException {
        EhsTaskInfo en = null;
        try {
            en = validateAndConvertDtoToEntity(editDto);
        } catch (QCPromptException e) {
            return e.getMessage();
        }
        //判断任务ID是否非空
        if (en == null)
            return QCUnifyReturnValue.Warn("修改的任务信息不存在");
        if (StringUtils.isBlank(en.getTaskid()))
            return QCUnifyReturnValue.Warn("修改的任务信息记录ID不能为空");

        //调用一次预览结果，判断结果是否通过验证
        TaskPreviewResultDto previewResult = getPreviewResult(en, editDto.getChecktableids(), editDto.getGroupobjids());
        if (previewResult.isIsok() == false)
            return "验证任务信息未通过，" + previewResult.getMsg();

        taskInfoRepository.updateById(en);

        return QCUnifyReturnValue.Success();
    }

    /***
     * 验证任务信息DTO并转换为Entity，用于新增、修改、预览方法统一调用
     *
     * @param dto 新增或修改的任务信息DTO
     * @return qc.module.ehs.entity.EhsTaskInfo
     * @author QuCheng Tech
     * @since 2025/1/16
     */
    EhsTaskInfo validateAndConvertDtoToEntity(TaskAddOrEditDto dto) throws QCPromptException {
        //1.DTO有效性验证
        if (dto == null)
            throw new QCPromptException("任务对象不能为空");
        if (StringUtils.isBlank(dto.getOrgcode()))
            throw new QCPromptException("组织机构代码不能为空");
        if (StringUtils.isBlank(dto.getTasktitle()))
            throw new QCPromptException("任务标题不能为空");
        if (StringUtils.isBlank(dto.getCatname()))
            throw new QCPromptException("任务分类名称不能为空");
        if (StringUtils.isBlank(dto.getPlanbegintm()))
            throw new QCPromptException("计划开始时间不能为空");
        if (StringUtils.isBlank(dto.getPlanendtm()))
            throw new QCPromptException("计划截止时间不能为空");
        if (dto.getPlanfrequencycount() < 0x1)
            throw new QCPromptException("每个周期内计划执行次数不能小于1");

        //计划起止时间处理
        Date planBeginDate = null;
        Date planEndDate = null;
        if (StringUtils.isNotBlank(dto.getPlanbegintm())) {
            try {
                planBeginDate = DateUtil.parseDate(dto.getPlanbegintm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("计划开始日期转换错误");
            }
        }
        if (StringUtils.isNotBlank(dto.getPlanendtm())) {
            try {
                planEndDate = DateUtil.parseDate(dto.getPlanendtm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("计划截止日期转换错误");
            }
        }
        if (planBeginDate.after(planEndDate))
            throw new QCPromptException("计划开始时间不能在计划截止时间之后。");

        //2.addDto转换为entity，设置属性值
        EhsTaskInfo en = EhsTaskInfoMapper.MAPPER.addOrEditDtoToEntity(dto);

        //最终返回的对象，如果为修改时默认为已存在的Entity，在使用本次转换后的实体对部分属性进行赋值
        EhsTaskInfo result = null;
        //根据转换后的entity是否有任务ID判定为是新增还是修改，如果是修改时判断记录是否存在
        if (StringUtils.isNotBlank(dto.getTaskid())) {
            //根据任务ID查询任务，判断任务是否存在
            result = taskInfoRepository.selectById(dto.getTaskid());
            if (result == null)
                throw new QCPromptException("指定的任务ID数据不存在。");
            result = en;
        } else {
            //如果没有任务ID，判定为是新增情况，对默认值进行赋值
            result = en;
            result.setIntm(DateUtil.getNowDate());
            result.setHasdispatch(false);
            result.setHasfinish(false);
            result.setHasend(false);
            result.setExeccount(0x0);
            result.setExecidentifycount(0x0);
            result.setExectroublecount(0x0);
        }

        //转换为Entity后对枚举类型非空和有效值进行判断
        if (result.getTasktype() == null)
            throw new QCPromptException("任务分类不能为空。");
        if (result.getNotnull().booleanValue() == true) {
            if (result.getObjtype() == null || result.getObjtype() == EhsTaskDestObjectTypeEnum.UNDEFINED)
                throw new QCPromptException("任务目标对象非空时，任务目标对象类型不能为空");
        }
        if (result.getPlanfrequencytype() == null)
            throw new QCPromptException("计划执行周期类型不能为空");

        //根据任务大类设置任务分组对象类型：任务分组类型可以分为按单元、隐患、自定义3种。
        if (result.getTasktype() == EhsTaskCategoryTypeEnum.SECURITY_CHECK ||
                result.getTasktype() == EhsTaskCategoryTypeEnum.EQUIPMENT_MAINTENANCE) {
            //针对自查、设备设施维护保养类型的任务，按单元进行分组，设置任务分组对象类型为单元
            result.setGroupobjtype(EhsTaskGroupObjectTypeEnum.UNIT);
        } else if (result.getTasktype() == EhsTaskCategoryTypeEnum.HIDDEN_DANGER_CONTROL) {
            //针对隐患治理类型的任务，按隐患进行分组，设置任务分组对象类型为隐患
            result.setGroupobjtype(EhsTaskGroupObjectTypeEnum.TROUBLE);
        } else if (result.getTasktype() == EhsTaskCategoryTypeEnum.INSPECT) {
            //针对专项检查/督查类型的任务，按自定义分组，设置任务分组对象类型为未定义
            result.setGroupobjtype(EhsTaskGroupObjectTypeEnum.CUSTOM);
        } else {
            //其他任务类型，设置任务分组类型为自定义
            result.setGroupobjtype(EhsTaskGroupObjectTypeEnum.CUSTOM);
        }

        //设置任务的计划起始时间和截止时间
        result.setPlanbegintm(planBeginDate);
        result.setPlanendtm(planEndDate);

        if (result.getPlantotalcount() == null)
            result.setPlantotalcount(0x1);

        return result;
    }

    /***
     * 根据任务信息Entity获取预览结果
     *
     * @param taskinfo 任务信息Entity
     * @param checktableids 检查表ID集合
     * @param groupobjids 任务分组对象ID集合，一般为单元ID集合
     * @return qc.module.ehs.dto.task.TaskPreviewResultDto
     * @author QuCheng Tech
     * @since 2025/1/16
     */
    TaskPreviewResultDto getPreviewResult(EhsTaskInfo taskinfo, String[] checktableids, String[] groupobjids) {
        TaskPreviewResultDto result = new TaskPreviewResultDto();
        //默认结果为预览不通过
        result.setIsok(false);

        if (taskinfo != null) {
            //验证检查表
            //先判断任务信息中是否设置必须要有检查表
            if (taskinfo.getNeedchecktable().booleanValue() == false) {
                //不需要检查表，不进行验证；在msg中进行提示
                result.setIsok(true);
                result.setMsg("本次任务设置不要求填写检查表。");
            }

            //获取任务分组的对象类型
            EhsTaskGroupObjectTypeEnum groupobjtype = taskinfo.getGroupobjtype();
            result.setGrouptypevalue(groupobjtype.getIndex());
            result.setGrouptypename(groupobjtype.getName());

            //获取任务的检查表
            List<CheckTableDto> checktables = new ArrayList<>();
            if (checktableids != null && checktableids.length > 0x0) {
                //获取检查表信息，获取每个检查表适用的单元分类和单元ID集合
                for (String tableId : checktableids) {
                    checktables.add(checkTableService.get(tableId));
                }

                result.setChecktables(checktables.stream().map(p -> p.getTitle()).toArray(String[]::new));
            } else {
                //没有检查表
                result.setMsg("检查表集合为空，未选择任务使用的检查表。");
            }

            if (groupobjtype == EhsTaskGroupObjectTypeEnum.UNIT) {
                //在任务分组对象类型为单元时，获取单元信息；
                if (groupobjids != null && groupobjids.length > 0x0) {
                    //根据单元ID集合获取单元信息，并获取单元适用的检查表情况
                    int hasNoCheckTableUnitCount = 0x0;//没有对应检查表的单元
                    int hasMultiCheckTableUnitCount = 0x0;//有多个对应检查表的单元

                    List<String> unitnames = new ArrayList<>();
                    List<String> unitCheckTableNames = new ArrayList<>();
                    for (String unitid : groupobjids) {
                        try {
                            EhsUnitDto unit = unitInfoService.get(unitid);
                            if (unit != null) {
                                unitnames.add(unit.getUnitname());
                                if (checktables != null && checktables.size() > 0x0) {
                                    int getCheckTableByUnitCategoryAndIdCount = 0x0;
                                    StringBuilder matchTableNames = new StringBuilder();
                                    //获取单元对应的检查表
                                    List<CheckTableDto> filterByUnitId = checktables.stream().filter(p -> p.getUnitids() != null && p.getUnitids().length > 0x0 && Arrays.stream(p.getUnitids()).anyMatch(s -> s.equalsIgnoreCase(unitid))).collect(Collectors.toList());
                                    if (filterByUnitId != null && filterByUnitId.size() > 0x0) {
                                        getCheckTableByUnitCategoryAndIdCount += filterByUnitId.size();
                                        //如果根据指定单元ID获取到的检查表为1个即该单元使用此检查表，如果根据指定单元ID获取到的检查表≥2个则提示匹配到多个
                                        if (filterByUnitId.size() == 0x1) {
                                            //不再继续根据单元分类进行匹配检查表
                                            unitCheckTableNames.add(filterByUnitId.get(0x0).getTitle());
                                            continue;
                                        } else {
                                            //根据指定单元ID匹配的检查表数量≥2
                                            for (CheckTableDto ct : filterByUnitId) {
                                                matchTableNames.append(ct.getTitle() + ",");
                                            }
                                        }
                                    }
                                    //获取单元分类对应的检查表，根据单元分类获取时要求该检查表适用单元集合为空
                                    List<CheckTableDto> filterByUnitCategory = checktables.stream().filter(p -> (p.getUnitids() == null || p.getUnitids().length < 0x1) && StringUtils.equalsIgnoreCase(unit.getUccd(), p.getUccd())).collect(Collectors.toList());
                                    if (filterByUnitCategory != null && filterByUnitCategory.size() > 0x0) {
                                        //如果根据单元分类得到的检查表数量为1即使用匹配到的检查表，如果数量≥2则提示匹配到多个
                                        getCheckTableByUnitCategoryAndIdCount += filterByUnitCategory.size();
                                        if (filterByUnitCategory.size() == 0x1) {
                                            //不再继续匹配，直接使用匹配到的唯一检查表进行返回
                                            unitCheckTableNames.add(filterByUnitCategory.get(0x0).getTitle());
                                            continue;
                                        } else {
                                            //根据单元分类匹配到的检查表数量≥2
                                            for (CheckTableDto ct : filterByUnitCategory) {
                                                matchTableNames.append(ct.getTitle() + ",");
                                            }
                                        }
                                    }
                                    if (getCheckTableByUnitCategoryAndIdCount == 0x0)//单元分类和单元ID均没有检查表
                                        hasNoCheckTableUnitCount++;
                                    if (getCheckTableByUnitCategoryAndIdCount >= 0x2)//单元分类和单元ID有2个或以上检查表
                                        hasMultiCheckTableUnitCount++;

                                    if (matchTableNames.length() > 0x0)
                                        unitCheckTableNames.add(matchTableNames.toString());
                                    else
                                        unitCheckTableNames.add("");
                                } else {
                                    //没有任何检查表
                                    hasNoCheckTableUnitCount++;

                                    unitCheckTableNames.add("");
                                }
                            }
                        } catch (QCPromptException e) {
                            e.printStackTrace();
                        }
                    }

                    result.setUnits(unitnames.stream().toArray(String[]::new));
                    result.setUnitchecktables(unitCheckTableNames.stream().toArray(String[]::new));
                    //遍历完每个单元，根据结果显示提示信息
                    if (hasNoCheckTableUnitCount == 0x0 && hasMultiCheckTableUnitCount == 0x0) {
                        //每个单元均有唯一对应的检查表
                        result.setIsok(true);
                    } else {
                        if (hasNoCheckTableUnitCount > 0x0) {
                            if (hasMultiCheckTableUnitCount > 0x0) {
                                result.setMsg("共有" + hasNoCheckTableUnitCount + "个单元没有对应的检查表，共有" + hasMultiCheckTableUnitCount + "个单元有多个对应的检查表。");
                            } else {
                                result.setMsg("共有" + hasNoCheckTableUnitCount + "个单元没有对应的检查表。");
                            }
                        }
                    }
                } else {
                    //在任务的分组对象类型为单元时，单元ID集合信息为空
                    result.setMsg("单元集合为空，未选择任务单元。");
                }
            } else {
                //任务分组对象类型不为单元，为自定义分组时，不需要获取分组与检查表的对应关系
                //设置预览结果为ok
                result.setIsok(true);
                result.setMsg("任务下发时不指定具体执行单元，在填写执行记录时自动根据选择的单元匹配对应的检查表。");
                //在任务新增时还没有自定义分组信息，在修改时查询任务分组信息
                if (StringUtils.isNotBlank(taskinfo.getTaskid())) {
                    //查询任务分组信息
                    List<TaskGroupInfoDto> groups = taskGroupService.getTaskGroups(taskinfo.getTaskid());
                    if (groups != null && groups.size() > 0x0) {
                        result.setGroups(groups.stream().map(p -> p.getGroupname()).toArray(String[]::new));
                    }
                }
            }

        } else {
            result.setMsg("任务对象信息错误，转换后的对象为空。");
        }

        return result;
    }

    /***
     * 任务信息预览
     *
     * @param dto 任务信息DTO
     * @return qc.module.ehs.dto.task.TaskPreviewResultDto
     * @author QuCheng Tech
     * @since 2025/1/16
     */
    public TaskPreviewResultDto preview(TaskAddOrEditDto dto) {
        EhsTaskInfo en = null;
        try {
            en = validateAndConvertDtoToEntity(dto);
        } catch (QCPromptException e) {
            TaskPreviewResultDto result = new TaskPreviewResultDto();
            //默认结果为预览不通过
            result.setIsok(false);
            result.setMsg(e.getMessage());

            return result;
        }

        return getPreviewResult(en, dto.getChecktableids(), dto.getGroupobjids());
    }

    /**
     * 删除安全任务
     * 仅支持对未派单的任务进行删除；删除采用物理删除，同时删除任务分组表和任务项表中的记录；
     *
     * @param id 任务ID
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/14
     */
    public String delete(String id) {

        //获取指定任务信息
        EhsTaskInfo task = taskInfoRepository.selectById(id);
        if (Objects.nonNull(task)) {

            //已派单的任务提示不能删除
            if (task.getHasdispatch()) return QCUnifyReturnValue.Warn("已派单的任务不能进行删除操作。");

            //获取指定任务的任务分组，获取指定任务和任务分组的任务项，同时删除任务分组和任务项记录
            List<TaskGroupInfoDto> groups = taskGroupService.getTaskGroups(id);
            if (CollectionUtils.isNotEmpty(groups)) {
                List<String> groupIds = groups.stream().map(TaskGroupInfoDto::getGroupid).collect(Collectors.toList());

                List<TaskItemInfoDto> items = taskItemService.getItemsByTaskIdAndGroupIds(id, groupIds);
                if (Objects.nonNull(items)) {
                    List<String> itemIds = items.stream().map(TaskItemInfoDto::getItemid).collect(Collectors.toList());
                    taskItemService.deleteByIds(itemIds);
                }

                taskGroupService.deleteByIds(groupIds);
            }
            taskInfoRepository.deleteById(id);
        }
        return QCUnifyReturnValue.Success();
    }

    /**
     * 获取安全任务分组关联的对象
     *
     * @param id 任务ID
     * @return TaskGroupObjectsDto
     * @author QuCheng Tech
     * @since 2024/11/14
     */
    public TaskGroupObjectsDto getTaskGroupObjects(String id) {

        TaskGroupObjectsDto result = new TaskGroupObjectsDto();

        //获取指定任务信息
        EhsTaskInfo task = taskInfoRepository.selectById(id);
        if (Objects.nonNull(task)) {
            //获取任务关联的分组对象ID集合
            List<String> objIds = taskGroupService.getObjectIds(id, task.getGroupobjtype());

            result.setObjecttype(task.getGroupobjtype().getIndex());
            result.setObjectids(objIds);
        }

        return result;
    }

    /**
     * 设置任务分组
     * <p>
     * 根据任务中的对象类型，选择任务关联的对象集合；
     * 不管任务是否派单均能进行该操作，要求任务的执行完成为false并且终止/取消为false；
     * 该操作不影响已执行的分组和任务项；
     * 设置分组的对象与已有的分组中的对象可能有3种情况：已存在相同、本次新增加、本次删除原有；
     * 已存在相同：不需要对分组信息进行任何操作；
     * 本次新增加：在分组中添加相应信息，任务项的执行周期从添加的当前时间开始计算；
     * 本次删除原有：在分组中对本次删除的分组设置终止/取消为true，同时对任务项中设置终止/取消为true；
     * <p>
     * 2024/11/18修改：任务未派单才能进行该操作。
     *
     * @param dto
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/19
     */
    public String setTaskGroups(TaskSetGroupObjectsDto dto) {
        if (dto == null) return QCUnifyReturnValue.Warn("请求对象不能为空");
        if (StringUtils.isBlank(dto.getTaskid())) return QCUnifyReturnValue.Warn("任务ID不能为空");

        /*
         * 1.获取指定任务信息
         * 2.如果任务已执行完成并且终止/取消，提示
         * 3.先获取任务已有的对象ID集合
         * 4.设置分组的对象与已有的分组中的对象可能有3种情况：已存在相同、本次新增加、本次删除原有；
         * 4.1 已存在相同对象：不需要对分组信息进行任何操作
         * 4.2 是本次新增加的：新增分组信息，
         * 4.3 本次删除原有：分组中本次删除的分组设置终止/取消为true，同时对任务项中设置终止/取消为true
         * */

        EhsTaskInfo task = taskInfoRepository.selectById(dto.getTaskid());
        if (Objects.nonNull(task)) {

            //任务已完成或者已终止则提示
            if (task.getHasfinish() || task.getHasend())
                return QCUnifyReturnValue.Warn("任务已完成或已终止，不再进行设置任务分组操作。");
            //任务未派单才能进行该操作。
            if (task.getHasdispatch())
                return QCUnifyReturnValue.Warn("任务已派单，无法设置任务分组操作");

            //如果任务分组指定的对象类型是单元，获取指定单元信息集合，新增分组时责任部门信息从单元中获取
            List<EhsUnitDto> units = new ArrayList<>();
            if (dto.getGroupobjtype() == EhsTaskDestObjectTypeEnum.UNIT.getIndex()) {
                units = unitInfoService.getUnitsByIds(Arrays.asList(dto.getGroupobjids()));
            }

            List<TaskGroupAddDto> addGroups = new ArrayList<>();//需要新增的分组
            List<String> endGroupIds = new ArrayList<>();//删除原有的：设置为终止

            //获取任务已有的分组对象ID集合
            List<String> objIds = taskGroupService.getObjectIds(dto.getTaskid(), task.getGroupobjtype());
            if (CollectionUtils.isEmpty(objIds)) {
                //不存在任何分组对象ID集合，新增分组
                for (String objId : dto.getGroupobjids()) {
                    TaskGroupAddDto group = new TaskGroupAddDto();
                    group.setTaskid(task.getTaskid());
                    if (dto.getGroupobjtype() == EhsTaskDestObjectTypeEnum.UNIT.getIndex()) {
                        EhsUnitDto unit = units.stream().filter(p -> p.getUnitid().equals(objId)).findAny().orElse(null);
                        group.setGroupname(unit.getUnitname());
                        group.setUnitid(unit.getUnitid());
                        group.setUnitname(unit.getUnitname());
                        //将单元的责任部门和责任人写入任务分组表中的责任部门和参与组员1中；
                        //如果单元中的责任人和安全员不为同一个人，将单元中的安全员写入任务分组表中参与组员2中。
                        group.setResdeptid(unit.getResdeptid());
                        group.setResdeptname(unit.getResdeptname());
                        group.setResuserid1(unit.getResuserid());
                        group.setResusername1(unit.getResusername());
                        if (unit.getResuserid() != unit.getSafeuserid()) {
                            group.setResuserid2(unit.getSafeuserid());
                            group.setResusername2(unit.getSafeusername());
                        }
                        //分组排序号采用：单元所在层级数+3位单元排序号；
                        int level = unit.getLevelcode().length() / 3;
                        int odr = 0x0;
                        if (unit.getOdr() == null) {
                            odr = Integer.parseInt(level + "" + 999);
                        } else {
                            //判断单元排序号是几位数，最多有三位，不足三位前面补0
                            if (pan(unit.getOdr()) == 0x1) {
                                odr = Integer.parseInt(level + "00" + unit.getOdr());
                            } else if (pan(unit.getOdr()) == 0x2) {
                                odr = Integer.parseInt(level + "0" + unit.getOdr());
                            } else {
                                odr = Integer.parseInt(level + "" + unit.getOdr());
                            }
                        }
                        group.setOdr(odr);
                    } else {
                        //
                    }
                    addGroups.add(group);
                }

            } else {
                //任务已有分组对象ID集合，根据传入的分组对象ID，判断是否已经存在，存在则表示已有此分组，不存在则新增分组
                for (String objId : dto.getGroupobjids()) {
                    //从原有的任务对象ID中查找本次设置的对象ID
                    String objectId = objIds.stream().filter(id -> id.equals(objId)).findAny().orElse(null);

                    if (objectId != null) {
                        //情况一：已存在相同对象，不需要对分组信息进行任务操作；
                    } else {
                        //情况二：是本次新增的对象
                        TaskGroupAddDto group = new TaskGroupAddDto();
                        group.setTaskid(task.getTaskid());
                        if (dto.getGroupobjtype() == EhsTaskDestObjectTypeEnum.UNIT.getIndex()) {
                            EhsUnitDto unit = units.stream().filter(p -> p.getUnitid().equals(objId)).findAny().orElse(null);
                            group.setGroupname(unit.getUnitname());
                            group.setUnitid(unit.getUnitid());
                            group.setUnitname(unit.getUnitname());
                            //将单元的责任部门和责任人写入任务分组表中的责任部门和参与组员1中；
                            //如果单元中的责任人和安全员不为同一个人，将单元中的安全员写入任务分组表中参与组员2中。
                            group.setResdeptid(unit.getResdeptid());
                            group.setResdeptname(unit.getResdeptname());
                            group.setResuserid1(unit.getResuserid());
                            group.setResusername1(unit.getResusername());
                            if (unit.getResuserid() != unit.getSafeuserid()) {
                                group.setResuserid2(unit.getSafeuserid());
                                group.setResusername2(unit.getSafeusername());
                            }
                            //分组排序号采用：单元所在层级数+3位单元排序号；
                            int level = unit.getLevelcode().length() / 3;
                            int odr = 0x0;
                            if (unit.getOdr() == null) {
                                odr = Integer.parseInt(level + "" + 999);
                            } else {
                                //判断单元排序号是几位数，最多有三位，不足三位前面补0
                                if (pan(unit.getOdr()) == 0x1) {
                                    odr = Integer.parseInt(level + "00" + unit.getOdr());
                                } else if (pan(unit.getOdr()) == 0x2) {
                                    odr = Integer.parseInt(level + "0" + unit.getOdr());
                                } else {
                                    odr = Integer.parseInt(level + "" + unit.getOdr());
                                }
                            }
                            group.setOdr(odr);
                        } else {
                            //
                        }
                        addGroups.add(group);
                    }
                }

                //获取指定任务的分组
                List<TaskGroupInfoDto> groups = taskGroupService.getTaskGroups(task.getTaskid());
                //从传入的分组对象ID集合中查找已有分组对象ID，判断是否存在，不存在则删除已有的分组:在分组中对本次删除的分组设置终止/取消为true，同时对任务项中设置终止/取消为true；
                //情况三：原有现在没有，本次删除原有
                for (String objId : objIds) {
                    //从本次设置的任务对象ID中查找原有的对象ID
                    String objectId = Arrays.asList(dto.getGroupobjids()).stream().filter(id -> id.equals(objId)).findAny().orElse(null);
                    if (objectId == null) {
                        if (dto.getGroupobjtype() == EhsTaskDestObjectTypeEnum.UNIT.getIndex()) {
                            TaskGroupInfoDto group = groups.stream().filter(p -> p.getTaskid().equals(task.getTaskid())
                                    && p.getUnitid().equals(objId)).findAny().orElse(null);
                            if (group != null) {
                                //设置分组为终止
                                endGroupIds.add(group.getGroupid());
                            }
                        } else if (dto.getGroupobjtype() == EhsTaskDestObjectTypeEnum.HAZARD.getIndex() ||
                                dto.getGroupobjtype() == EhsTaskDestObjectTypeEnum.FIRST_TYPE_HAZARD.getIndex() ||
                                dto.getGroupobjtype() == EhsTaskDestObjectTypeEnum.SECOND_TYPE_HAZARD.getIndex()) {
                            TaskGroupInfoDto group = groups.stream().filter(p -> p.getTaskid().equals(task.getTaskid())
                                    && p.getHazardid().equals(objId)).findAny().orElse(null);
                            if (group != null) {
                                //设置分组为终止
                                endGroupIds.add(group.getGroupid());
                            }
                        } else if (dto.getGroupobjtype() == EhsTaskDestObjectTypeEnum.FACILITY.getIndex()) {
                            TaskGroupInfoDto group = groups.stream().filter(p -> p.getTaskid().equals(task.getTaskid())
                                    && p.getFacilityid().equals(objId)).findAny().orElse(null);
                            if (group != null) {
                                //设置分组为终止
                                endGroupIds.add(group.getGroupid());
                            }
                        } else {
                            //
                        }
                    }
                }
            }

            //新增分组
            if (CollectionUtils.isNotEmpty(addGroups)) {
                for (TaskGroupAddDto groupAddDto : addGroups) {
                    taskGroupService.add(groupAddDto);
                }
            }

            //设置分组为终止
            if (CollectionUtils.isNotEmpty(endGroupIds)) {
                for (String groupId : endGroupIds) {
                    taskGroupService.end(groupId);
                }
            }
        }

        return QCUnifyReturnValue.Success();
    }

    /**
     * 判断一个数字是几位数
     *
     * @param num
     * @return
     */
    private static int pan(int num) {
        int count = 0;
        while (num > 10) {
            num /= 10;
            count++;
        }
        return count + 1;
    }

    /**
     * 对指定的安全任务进行派单
     * <p>
     * 对指定的安全任务进行派单操作；派单后不能取消，只能终止任务；对已经派单或结束（终止/完成）的任务不能进行派单；
     * 对任务进行派单时才根据任务分组生成任务项，任务项中均为已经派单的任务；根据任务项中的计划执行时间确定在不同时间段内（本月、本年）内的任务；
     *
     * @param dto 任务派单DTO
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/15
     */
    public String dispatch(TaskDispatchDto dto) throws QCPromptException {
        //1.DTO有效性验证
        if (dto == null) return QCUnifyReturnValue.Warn("派单对象不能为空");
        if (StringUtils.isBlank(dto.getId())) return QCUnifyReturnValue.Warn("任务ID不能为空");
        if (StringUtils.isBlank(dto.getBegintm())) return QCUnifyReturnValue.Warn("派单后任务计划执行的起始时间不能为空");
        if (StringUtils.isBlank(dto.getEndtm())) return QCUnifyReturnValue.Warn("派单后任务计划执行的截止时间不能为空");

        //计划时间处理
        Date planBeginTime = null;
        Date planEndTime = null;
        if (StringUtils.isNotBlank(dto.getBegintm())) {
            try {
                planBeginTime = DateUtil.parseDate(dto.getBegintm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("任务派单中的开始日期转换错误");
            }
        }
        if (StringUtils.isNotBlank(dto.getEndtm())) {
            try {
                planEndTime = DateUtil.parseDate(dto.getEndtm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("任务派单中的截止日期转换错误");
            }
        }

        //获取指定任务信息
        EhsTaskInfo taskInfo = taskInfoRepository.selectById(dto.getId());
        if (Objects.isNull(taskInfo)) return null;

        //判断派单时选择的起止时间只能在任务的计划时间段内；
        if (planBeginTime.before(taskInfo.getPlanbegintm())) {
            throw new QCPromptException("派单时计划开始时间不在任务的计划时间段内。");
        }
        if (planEndTime.after(taskInfo.getPlanendtm())) {
            throw new QCPromptException("派单时计划截止时间不在任务的计划时间段内。");
        }

        //对已经派单或结束（终止/完成）的任务不能进行派单；
        if (taskInfo.getHasdispatch())
            return QCUnifyReturnValue.Warn("任务已经派单，不能重复派单。");
        if (taskInfo.getHasfinish() || taskInfo.getHasend())
            return QCUnifyReturnValue.Warn("已经执行完成或者终止的任务不能进行派单操作。");

        //获取指定任务的分组
        List<TaskGroupInfoDto> groups = taskGroupService.getTaskGroups(dto.getId());
        if (CollectionUtils.isEmpty(groups)) return QCUnifyReturnValue.Warn("当前任务无分组，请设置任务分组");

        List<EhsTaskItem> addItems = new ArrayList<>();//要新增的任务项集合

        //对任务进行派单时才根据任务分组生成任务项，任务项中均为已经派单的任务；根据任务项中的计划执行时间确定在不同时间段内（本月、本年）内的任务；
        //根据任务的计划执行周期类型和计划起止时间，生成每个周期的计划起止时间和周期文字描述；然后生成的每个周期计划与每一个分组生成任务项

        //循环计划起止时间，处理生成任务项
        //Date planBeginTime = taskInfo.getPlanbegintm();
        //Date planEndTime = taskInfo.getPlanendtm();
        int whileCount = 0x0;//循环次数
        while (planBeginTime.before(planEndTime)) {
            Date currentBeginTm = planBeginTime;
            String currentTimeStr = "";
            int year = DateUtil.getYear(currentBeginTm);
            int mouth = DateUtil.getMonth(currentBeginTm);
            int day = DateUtil.getDay(currentBeginTm);
            whileCount++;
            boolean isSingleExec = false;

            //根据任务的计划执行周期类型,计算当前结束时间(也是下一周期的开始时间)
            if (taskInfo.getPlanfrequencytype() == TimeRangeLengthEnum.MINUTE) {
                //分钟
                return QCUnifyReturnValue.Warn("频次任务的执行周期不能小于1天。");
            } else if (taskInfo.getPlanfrequencytype() == TimeRangeLengthEnum.HOUR) {
                //小时
                return QCUnifyReturnValue.Warn("频次任务的执行周期不能小于1天。");
            } else if (taskInfo.getPlanfrequencytype() == TimeRangeLengthEnum.DAY) {
                //日
                planBeginTime = DateUtil.addDays(planBeginTime, 0x1);
                currentTimeStr = "第" + whileCount + "天";
            } else if (taskInfo.getPlanfrequencytype() == TimeRangeLengthEnum.WEEK) {
                //周，天数+7
                planBeginTime = DateUtil.addDays(planBeginTime, 0x7);
                currentTimeStr = "第" + whileCount + "周";
            } else if (taskInfo.getPlanfrequencytype() == TimeRangeLengthEnum.TEN_DAYS) {
                //旬
                planBeginTime = DateUtil.addTendays(planBeginTime, 0x1);
                if (day >= 1 && day <= 10) {
                    currentTimeStr = mouth + "月上旬";
                } else if (day >= 11 && day <= 20) {
                    currentTimeStr = mouth + "月中旬";
                } else if (day >= 21) {
                    currentTimeStr = mouth + "月下旬";
                }
            } else if (taskInfo.getPlanfrequencytype() == TimeRangeLengthEnum.MONTH) {
                //月
                planBeginTime = DateUtil.addMonths(planBeginTime, 0x1);
                currentTimeStr = year + "年" + mouth + "月";
            } else if (taskInfo.getPlanfrequencytype() == TimeRangeLengthEnum.QUARTER) {
                //季度，月份+3
                planBeginTime = DateUtil.addMonths(planBeginTime, 0x3);
                if (mouth >= 1 && mouth <= 3)
                    currentTimeStr += year + "年第一季度";
                else if (mouth >= 4 && mouth <= 6)
                    currentTimeStr += year + "年第二季度";
                else if (mouth >= 7 && mouth <= 9)
                    currentTimeStr += year + "年第三季度";
                else if (mouth >= 10)
                    currentTimeStr += year + "年第四季度";
            } else if (taskInfo.getPlanfrequencytype() == TimeRangeLengthEnum.YEAR) {
                //年
                planBeginTime = DateUtil.addYears(planBeginTime, 0x1);
                currentTimeStr = year + "年";
            } else {
                //自定义，当作单次任务执行
                planBeginTime = planEndTime;
                //plantmstr使用任务的起止时间，如：2024-11-01~2024-11-30
                currentTimeStr = DateUtil.getDateString(currentBeginTm) + "~" + DateUtil.getDateString(planBeginTime);
                isSingleExec = true;

            }

            if (!isSingleExec) {
                if (whileCount > 31) {
                    return QCUnifyReturnValue.Warn("根据当前任务周期和频次计算出的计划执行次数为" + whileCount + "，" +
                            "任务次数超过设定值，请将计划执行周期缩短或将执行频次增大。");
                }
            }

            //每个周期对应每个分组生成一个任务项
            for (TaskGroupInfoDto group : groups) {
                EhsTaskItem item = new EhsTaskItem();
                item.setItemid(IdentifierUtil.randomUUID());
                item.setTaskid(taskInfo.getTaskid());
                //任务项名称：如果是单次任务【派单，itemname中仅使用任务标题，不加时间文字；
                if (isSingleExec) {
                    item.setItemname(taskInfo.getTasktitle());
                } else {
                    item.setItemname(taskInfo.getTasktitle() + "(" + currentTimeStr + ")");
                }
                item.setGroupid(group.getGroupid());
                item.setOrgcode(taskInfo.getOrgcode());
                item.setCatname(taskInfo.getCatname());
                item.setTasktype(taskInfo.getTasktype());
                item.setPlantmstr(currentTimeStr);
                item.setPlanbegintm(currentBeginTm);
                item.setPlanendtm(DateUtil.addDays(planBeginTime, -1));
                item.setPlanfrequencytype(taskInfo.getPlanfrequencytype());
                item.setPlanfrequencycount(taskInfo.getPlanfrequencycount());
                item.setUnitid(group.getUnitid());
                item.setUnitname(group.getUnitname());
                item.setFacilityid(group.getFacilityid());
                item.setFacilityname(group.getFacilityname());
                item.setHazardid(group.getHazardid());
                item.setHazardname(group.getHazardname());
                //责任部门、参与组员1和参与组员2直接使用任务分组表中的对应属性值；
                item.setResdeptid(group.getResdeptid());
                item.setResdeptname(group.getResdeptname());
                item.setResuserid1(group.getResuserid1());
                item.setResusername1(group.getResusername1());
                item.setResuserid2(group.getResuserid2());
                item.setResusername2(group.getResusername2());
                item.setHasfinish(false);
                item.setHasend(false);
                item.setExeccount(0x0);
                item.setExecidentifycount(0X0);
                item.setExectroublecount(0x0);
                addItems.add(item);
            }
        }

        //新增任务项
        if (CollectionUtils.isNotEmpty(addItems)) {
            for (EhsTaskItem item : addItems) {
                taskItemService.add(item);
            }
        }

        //修改任务的派单状态
        taskInfo.setHasdispatch(true);
        taskInfoRepository.updateById(taskInfo);

        return QCUnifyReturnValue.Success();
    }

    /**
     * 对指定的安全任务设置为完成
     * <p>
     * 设置总任务为完成状态；
     * 需要判断任务分组的状态，每个分组的状态必须是执行完成为true或终止/取消为true；即要求每个分组都执行完、或者被终止/取消（不需要执行）；
     *
     * @param id 任务ID
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/15
     */
    public String finish(String id) {

        //获取指定任务信息
        EhsTaskInfo taskInfo = taskInfoRepository.selectById(id);
        if (Objects.isNull(taskInfo)) return null;

        //判断任务分组的状态，要求每个任务分组都是执行完成或者被终止/取消的状态
        //获取指定任务的所有分组
        List<TaskGroupInfoDto> taskGroups = taskGroupService.getTaskGroups(id);
        if (CollectionUtils.isNotEmpty(taskGroups)) {
            List<TaskGroupInfoDto> notEndGroups = taskGroups.stream().filter(p ->
                    p.isHasfinish() == false && p.isHasend() == false).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(notEndGroups))
                return QCUnifyReturnValue.Warn("指定任务下存在没有完成也没有终止/取消的分组，无法进行完成操作。");
        }

        //设置任务为完成
        taskInfo.setHasfinish(true);
        taskInfoRepository.updateById(taskInfo);
        return QCUnifyReturnValue.Success();
    }

    /**
     * 对指定的安全任务设置为终止
     * <p>
     * 要求同时满足以下条件才能进行终止：任务的派单状态为true，任务的执行完成为false，任务的终止/取消为false；
     * 任务的派单状态为false时，提示任务未派单，如不需要该任务可以直接删除；
     * 任务的执行完成为true时，提示任务已经执行完成，无需进行终止；
     * 任务的终止/取消为true时，提示任务已终止/取消，无需重复操作；
     * 设置任务为终止时，需要同步对任务分组和任务项中执行完成为false且终止/取消为false的设置终止/取消为true；
     *
     * @param id 任务ID
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/15
     */
    public String end(String id) {

        //获取指定任务信息
        EhsTaskInfo taskInfo = taskInfoRepository.selectById(id);
        if (Objects.isNull(taskInfo)) return null;

        //要求同时满足以下条件才能进行终止：任务的派单状态为true，任务的执行完成为false，任务的终止/取消为false；
        //任务的派单状态为false时，提示任务未派单，如不需要该任务可以直接删除；
        if (!taskInfo.getHasdispatch())
            return QCUnifyReturnValue.Warn("指定任务未派单，如果不需要该任务可以直接删除。");

        //任务的执行完成为true时，提示任务已经执行完成，无需进行终止；
        if (taskInfo.getHasfinish())
            return QCUnifyReturnValue.Warn("任务已经执行完成，无需进行终止。");

        //任务的终止/取消为true时，提示任务已终止/取消，无需重复操作；
        if (taskInfo.getHasend())
            return QCUnifyReturnValue.Warn("任务已经终止/取消，无需重复操作。");

        //设置任务为终止时，需要同步对任务分组和任务项中执行完成为false且终止/取消为false的设置终止/取消为true；
        //获取指定任务分组
        List<TaskGroupInfoDto> taskGroups = taskGroupService.getTaskGroups(id);
        if (CollectionUtils.isNotEmpty(taskGroups)) {

            //任务分组中执行完成为false且终止/取消为false的设置终止/取消为true
            List<TaskGroupInfoDto> notEndGroups = taskGroups.stream().filter(p ->
                    p.isHasfinish() == false && p.isHasend() == false).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(notEndGroups)) {
                List<String> groupIds = notEndGroups.stream().map(TaskGroupInfoDto::getGroupid).collect(Collectors.toList());
                for (String groupId : groupIds) {
                    taskGroupService.end(groupId);//同时会设置任务项中执行完成为false且终止/取消为false的设置终止/取消为true；
                }
            }
        }

        //设置任务为终止
        taskInfo.setHasend(true);
        taskInfoRepository.updateById(taskInfo);
        return QCUnifyReturnValue.Success();
    }

    /**
     * 对指定的安全任务设置为继续
     * <p>
     * 对已经终止的任务设置为继续；要求终止/取消为true的才能进行继续操作；
     * 设置任务为继续时，需要同步对任务分组和任务项中终止/取消为true的设置终止/取消为false；
     * 对执行完成为true的不进行修改，包含任务、任务分组和任务项均不进行修改；
     *
     * @param id 任务ID
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/15
     */
    public String setContinue(String id) {

        //获取指定任务信息
        EhsTaskInfo taskInfo = taskInfoRepository.selectById(id);
        if (Objects.isNull(taskInfo)) return null;

        //要求终止/取消为true的才能进行继续操作；
        if (taskInfo.getHasend()) {

            //设置任务为继续时，需要同步对任务分组和任务项中终止/取消为true的设置终止/取消为false；
            //获取指定任务分组
            List<TaskGroupInfoDto> taskGroups = taskGroupService.getTaskGroups(id);
            if (CollectionUtils.isNotEmpty(taskGroups)) {
                List<TaskGroupInfoDto> isEndGroups = taskGroups.stream().filter(p -> p.isHasend() == true).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(isEndGroups)) {
                    List<String> groupIds = isEndGroups.stream().map(TaskGroupInfoDto::getGroupid).collect(Collectors.toList());
                    for (String groupId : groupIds) {
                        taskGroupService.setContinue(groupId);//同时会设置任务项中终止/取消为true的设置为false；
                    }
                }
            }

            //设置任务终止/取消为false
            taskInfo.setHasend(false);
            taskInfoRepository.updateById(taskInfo);
        }
        return QCUnifyReturnValue.Success();
    }

    /**
     * 查询
     * <p>
     * 分页查询，表格显示任务信息表；
     * 可以根据指定部门进行过滤；指定部门时先在任务分组表中按照责任部门匹配，没有在任务分组中的责任部门的任务不返回；
     *
     * @param condition 查询条件
     * @return TaskConsoleQueryResultDto
     * @author QuCheng Tech
     * @since 2024/11/18
     */
    public TaskPaginationQueryResultDto query(TaskConsoleQueryConditionDto condition) throws QCPromptException {
        //1.查询条件有效性验证
        if (condition == null)
            throw new QCPromptException("查询任务列表的条件对象不能为空");
        if (StringUtils.isBlank(condition.getOrgcode()))
            throw new QCPromptException("查询任务列表的组织机构代码不能为空");
        if (StringUtils.isBlank(condition.getBegintm()))
            throw new QCPromptException("查询任务列表的计划起始时间不能为空");
        if (StringUtils.isBlank(condition.getEndtm()))
            throw new QCPromptException("查询任务列表的计划截止时间不能为空");

        //查询时间处理
        Date beginDate = null;
        Date endDate = null;
        if (StringUtils.isNotBlank(condition.getBegintm())) {
            try {
                beginDate = DateUtil.parseDate(condition.getBegintm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的开始日期转换错误");
            }
        }
        if (StringUtils.isNotBlank(condition.getEndtm())) {
            try {
                endDate = DateUtil.parseDate(condition.getEndtm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的截止日期转换错误");
            }
        }

        //2.设置返回结果默认值
        TaskPaginationQueryResultDto result = new TaskPaginationQueryResultDto();
        result.setTotal(0x0);
        result.setPages(0x1);
        result.setItems(new ArrayList<>());

        //3.构建任务项查询条件
        LambdaQueryWrapper<EhsTaskInfo> wrapper = new LambdaQueryWrapper<>();
        //组织机构代码，必须有，判断相等
        wrapper.eq(EhsTaskInfo::getOrgcode, condition.getOrgcode());
        //任务分类：默认为空或者为0是查询全部
        if (condition.getTasktype() != null && condition.getTasktype() != 0x0) {
            wrapper.eq(EhsTaskInfo::getTasktype, condition.getTasktype());
        }
        //任务的状态：全部、未派单、执行中、已完成、终止/取消；使用枚举EhsTaskStatusEnum；默认为空或者为0是查询全部
        if (condition.getStatus() != null && condition.getStatus() != 0x0) {
            if (condition.getStatus() == EhsTaskStatusEnum.NO_DISPATCH.getIndex()) {
                wrapper.eq(EhsTaskInfo::getHasdispatch, false);//未派单
            } else if (condition.getStatus() == EhsTaskStatusEnum.DOING.getIndex()) {
                wrapper.eq(EhsTaskInfo::getHasdispatch, true);//执行中：已派单
            } else if (condition.getStatus() == EhsTaskStatusEnum.COMPLETE.getIndex()) {
                wrapper.eq(EhsTaskInfo::getHasfinish, true);//已完成
            } else if (condition.getStatus() == EhsTaskStatusEnum.CANCELLED.getIndex()) {
                wrapper.eq(EhsTaskInfo::getHasend, true);//取消/终止
            }
        }
        //查询时间：任务计划的起始时间 >= 计划开始时间 and 任务计划的截止时间 <= 计划截止时间
        /*任务项的时间条件判断需要考虑以下几种不同情况：
            1.查询的起止时间前后都包含计划时间，查询时间段包含整个计划时间段；
            pbtm>=tm1 and petm<=tm2
            2.查询的起止时间前后都被计划时间包含，查询的时间段是计划时间段中间的部分时间；
            pbtm<=tm1 and petm>=tm2
            3.查询的起始时间被计划时间包含，查询时间段包含计划时间中的前部分时间；
            查询的截止时间被计划时间包含，查询时间段包含计划时间中的后部分时间；
            pbtm<=tm2 and petm>=tm1
        */
        Date finalBeginDate = beginDate;
        Date finalEndDate = endDate;
        //wrapper.and(q -> {
        //    q.ge(EhsTaskInfo::getPlanbegintm,finalBeginDate).le(EhsTaskInfo::getPlanendtm,finalEndDate);
        //}).or(q -> {
        //    q.le(EhsTaskInfo::getPlanbegintm, finalBeginDate).ge(EhsTaskInfo::getPlanendtm, finalEndDate);
        //}).or(q -> {
        //    q.le(EhsTaskInfo::getPlanbegintm,finalEndDate).ge(EhsTaskInfo::getPlanendtm,finalBeginDate);
        //});
        wrapper.and(q -> {
            (q.ge(EhsTaskInfo::getPlanbegintm, finalBeginDate).le(EhsTaskInfo::getPlanendtm, finalEndDate)).or()
                    .le(EhsTaskInfo::getPlanbegintm, finalBeginDate).ge(EhsTaskInfo::getPlanendtm, finalEndDate).or()
                    .le(EhsTaskInfo::getPlanbegintm, finalEndDate).ge(EhsTaskInfo::getPlanendtm, finalBeginDate);
        });
        //部门ID过滤：≤0表示无效；指定部门时先在任务分组表中按照责任部门匹配，没有在任务分组中的责任部门的任务不返回；
        if (condition.getDeptid() != null && condition.getDeptid() > 0x0) {
            List<String> taskIds = taskGroupService.getTaskIdByDeptId(condition.getDeptid());
            //如果根据部门ID获取到的任务ID集合为空，返回结果为null，不需要再进行后续的查询
            if (taskIds == null || taskIds.size() < 0x1)
                return result;

            //如果根据部门ID获取到的任务ID集合不为空，进行后续的查询
            wrapper.in(EhsTaskInfo::getTaskid, taskIds);
        }
        //关键字：可以匹配任务标题、内容
        if (StringUtils.isNotBlank(condition.getKeywords())) {
            wrapper.and(q -> {
                q.like(EhsTaskInfo::getTasktitle, condition.getKeywords()).or()
                        .like(EhsTaskInfo::getTaskcontent, condition.getKeywords());
            });
        }

        //按写入时间降序，保证新增记录在最前面方便进行查看和操作
        wrapper.orderByDesc(EhsTaskInfo::getIntm);

        //分页查询
        // 先构造一个Page对象
        int pageNum = QCConstant.PAGEING_DEFAULT_PAGE_NUM;
        int pageSize = QCConstant.PAGEING_DEFAULT_PAGE_SIZE;
        if (condition.getPage() > 0x0)
            pageNum = condition.getPage();
        if (condition.getPageSize() > 0x0)
            pageSize = condition.getPageSize();

        IPage<EhsTaskInfo> page = new Page<>(pageNum, pageSize);
        IPage<EhsTaskInfo> pageResult = taskInfoRepository.selectPage(page, wrapper);

        //获取查询结果
        result.setTotal(pageResult.getTotal());
        result.setPages(pageResult.getPages());
        List<EhsTaskInfo> ens = pageResult.getRecords();
        if (CollectionUtils.isNotEmpty(ens)) {
            List<TaskInfoDto> resultItems = new ArrayList<>();

            for (EhsTaskInfo en : ens) {
                //dto中需要检查表ID集合时使用entityToDto方法，不需要时使用toDto方法
                resultItems.add(EhsTaskInfoMapper.MAPPER.toDto(en));
            }

            result.setItems(resultItems);
        }

        return result;
    }

    /**
     * 查询指定单元的待办任务，返回的是任务信息表中的记录
     * <p>
     * 查询指定单元的待办任务，不管任务的责任部门和责任人；
     * 从任务项表中进行查询，查询的结果按照计划截止时间升序排列；
     *
     * @param unitId 单元ID
     * @return TaskConsoleQueryResultDto
     * @author QuCheng Tech
     * @since 2024/11/18
     */
    public List<TaskInfoDto> queryUnitTodoTask(String unitId) throws QCPromptException {
        if (StringUtils.isBlank(unitId))
            throw new QCPromptException("查询指定单元待办任务列表的单元ID不能为空");

        //任务项表与任务信息表联合查询；
        MPJLambdaWrapper<EhsTaskInfo> wrapper = new MPJLambdaWrapper<EhsTaskInfo>()
                .selectAll(EhsTaskItem.class)
                .selectAs(EhsTaskItem::getItemname, TaskInfoDto::getTasktitle)//使用任务项的名称作为返回DTO中的任务标题
                .rightJoin(EhsTaskItem.class, EhsTaskItem::getTaskid, EhsTaskInfo::getTaskid);
        //查询条件匹配：任务项表中的单元ID为传入的单元ID,执行完成为false并且取消/终止为false
        wrapper.eq(EhsTaskItem::getUnitid, unitId).eq(EhsTaskItem::getHasfinish, false).eq(EhsTaskItem::getHasend, false);
        //待办任务按计划截止时间升序排列返回
        wrapper.orderByAsc(EhsTaskItem::getPlanendtm);

        return taskInfoRepository.selectJoinList(TaskInfoDto.class, wrapper);
    }

    /**
     * 查询指定单元的已办任务
     * <p>
     * 查询指定单元的已办任务，不管任务的责任部门和责任人；
     * 从任务项表中进行查询，查询的结果按照计划开始时间升序排列；
     *
     * @param condition 查询条件
     * @return TaskConsoleQueryResultDto
     * @author QuCheng Tech
     * @since 2024/11/18
     */
    public TaskItemPaginationQueryResultDto queryUnitDoneTask(TaskConsoleUnitTaskItemPaginationQueryConditionDto condition) throws QCPromptException {
        //1.查询条件有效性验证
        if (condition == null)
            throw new QCPromptException("查询指定单元已办任务列表的条件对象不能为空");
        if (StringUtils.isBlank(condition.getUnitid()))
            throw new QCPromptException("查询指定单元已办任务列表的单元ID不能为空");
        if (StringUtils.isBlank(condition.getBegintm()))
            throw new QCPromptException("查询指定单元已办任务列表的计划起始时间不能为空");
        if (StringUtils.isBlank(condition.getEndtm()))
            throw new QCPromptException("查询指定单元已办任务列表的计划截止时间不能为空");

        //查询时间处理
        Date beginDate = null;
        Date endDate = null;
        if (StringUtils.isNotBlank(condition.getBegintm())) {
            try {
                beginDate = DateUtil.parseDate(condition.getBegintm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的计划开始日期转换错误");
            }
        }
        if (StringUtils.isNotBlank(condition.getEndtm())) {
            try {
                endDate = DateUtil.parseDate(condition.getEndtm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的计划截止日期转换错误");
            }
        }

        //2.设置返回结果默认值
        TaskItemPaginationQueryResultDto result = new TaskItemPaginationQueryResultDto();
        result.setTotal(0x0);
        result.setPages(0x1);
        result.setItems(new ArrayList<>());

        //3.根据单元ID和起止时间查询任务项
        LambdaQueryWrapper<EhsTaskItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EhsTaskItem::getUnitid, condition.getUnitid());
        //查询已办
        //任务状态：执行完成为true或者取消/终止为true
        wrapper.and(q -> {
            q.eq(EhsTaskItem::getHasfinish, true).or()
                    .eq(EhsTaskItem::getHasend, true);
        });
        //查询时间：起始时间 >= 计划开始时间 and 截止时间 <= 计划截止时间
        Date finalBeginDate = beginDate;
        Date finalEndDate = endDate;
        wrapper.and(q -> {
            q.ge(EhsTaskItem::getPlanbegintm, finalBeginDate).le(EhsTaskItem::getPlanendtm, finalEndDate);
        });
        wrapper.orderByAsc(EhsTaskItem::getPlanendtm);

        //4.分页查询
        // 先构造一个Page对象
        int pageNum = QCConstant.PAGEING_DEFAULT_PAGE_NUM;
        int pageSize = QCConstant.PAGEING_DEFAULT_PAGE_SIZE;
        if (condition.getPage() > 0x0)
            pageNum = condition.getPage();
        if (condition.getPageSize() > 0x0)
            pageSize = condition.getPageSize();

        IPage<EhsTaskItem> page = new Page<>(pageNum, pageSize);
        IPage<EhsTaskItem> pageResult = taskItemRepository.selectPage(page, wrapper);

        return result;
    }

    /**
     * 查询指定设备设置的待办任务
     * <p>
     * 查询指定设备设施的待办任务，不管任务的责任部门和责任人；
     * 从任务项表中进行查询，查询的结果按照计划截止时间升序排列；
     *
     * @param facilityId 设备设施ID
     * @return TaskConsoleQueryResultDto
     * @author QuCheng Tech
     * @since 2024/11/18
     */
    public List<TaskInfoDto> queryFacilityTodoTask(String facilityId) throws QCPromptException {
        //1.查询条件有效性验证
        if (StringUtils.isBlank(facilityId))
            throw new QCPromptException("查询指定设备设施待办任务列表的设备设施ID不能为空");

        //2.设置返回结果默认值，暂时不分页
        //TaskConsoleQueryResultDto result = new TaskConsoleQueryResultDto();
        //result.setTotal(0x0);
        //result.setPages(0x1);
        //result.setItems(new ArrayList<>());

        //3.根据设备设施ID查询任务项中待办的任务项，获取已办的任务ID集合
        List<String> taskIds = new ArrayList<>();
        List<TaskItemInfoDto> todoItems = taskItemService.queryTodoByFacilityId(facilityId);
        if (CollectionUtils.isNotEmpty(todoItems)) {
            taskIds = todoItems.stream().map(TaskItemInfoDto::getTaskid).collect(Collectors.toList());
            //如果根据单元获取到的待办任务项不为空，进行查询；如果根据单元获取到的待办任务项集合为空，不需要进行查询；
            //4.构建任务项查询条件
            LambdaQueryWrapper<EhsTaskInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(EhsTaskInfo::getTaskid, taskIds)
                    .orderByAsc(EhsTaskInfo::getPlanbegintm);

            //5.分页查询，暂时不分页
            // 先构造一个Page对象
            //int pageNum = QCConstant.PAGEING_DEFAULT_PAGE_NUM;
            //int pageSize = QCConstant.PAGEING_DEFAULT_PAGE_SIZE;
            //if (condition.getPage() > 0x0)
            //    pageNum = condition.getPage();
            //if (condition.getPageSize() > 0x0)
            //    pageSize = condition.getPageSize();

            //IPage<EhsTaskInfo> page = new Page<>(pageNum, pageSize);
            //IPage<EhsTaskInfo> pageResult = repository.selectPage(page, wrapper);

            List<EhsTaskInfo> ens = taskInfoRepository.selectList(wrapper);

            //6.获取查询结果，暂时不分页
            //result.setTotal(pageResult.getTotal());
            //result.setPages(pageResult.getPages());
            //List<EhsTaskInfo> ens = pageResult.getRecords();
            //if (CollectionUtils.isNotEmpty(ens)){
            //    result.setItems(EhsTaskInfoMapper.MAPPER.toDtoList(ens));
            //}
            //
            //return result;

            if (CollectionUtils.isNotEmpty(ens)) {
                List<TaskInfoDto> result = new ArrayList<>();

                for (EhsTaskInfo en : ens) {
                    //dto中需要检查表ID集合时使用entityToDto方法，不需要时使用toDto方法
                    result.add(EhsTaskInfoMapper.MAPPER.toDto(en));
                }

                return result;
            }
        }

        return null;
    }

    /**
     * 查询指定危险源的待办任务
     * <p>
     * 查询指定危险源的待办任务，不管任务的责任部门和责任人；
     * 可以用于查询指定隐患的治理任务；
     * 从任务项表中进行查询，查询的结果按照计划截止时间升序排列；
     *
     * @param hazardId 危险源ID
     * @return TaskConsoleQueryResultDto
     * @author QuCheng Tech
     * @since 2024/11/18
     */
    public List<TaskInfoDto> queryHazardTodoTask(String hazardId) throws QCPromptException {
        //1.查询条件有效性验证
        if (StringUtils.isBlank(hazardId))
            throw new QCPromptException("查询指定危险源待办任务列表的危险源ID不能为空");

        //2.设置返回结果默认值，暂时不分页
        //TaskConsoleQueryResultDto result = new TaskConsoleQueryResultDto();
        //result.setTotal(0x0);
        //result.setPages(0x1);
        //result.setItems(new ArrayList<>());

        //3.根据设备设施ID查询任务项中待办的任务项，获取已办的任务ID集合
        List<String> taskIds = new ArrayList<>();
        List<TaskItemInfoDto> todoItems = taskItemService.queryTodoByHazardId(hazardId);
        if (CollectionUtils.isNotEmpty(todoItems)) {
            taskIds = todoItems.stream().map(TaskItemInfoDto::getTaskid).collect(Collectors.toList());
            //如果根据单元获取到的待办任务项不为空，进行查询；如果根据单元获取到的待办任务项集合为空，不需要进行查询；
            //4.构建任务项查询条件
            LambdaQueryWrapper<EhsTaskInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(EhsTaskInfo::getTaskid, taskIds)
                    .orderByAsc(EhsTaskInfo::getPlanbegintm);

            //5.分页查询，暂时不分页
            // 先构造一个Page对象
            //int pageNum = QCConstant.PAGEING_DEFAULT_PAGE_NUM;
            //int pageSize = QCConstant.PAGEING_DEFAULT_PAGE_SIZE;
            //if (condition.getPage() > 0x0)
            //    pageNum = condition.getPage();
            //if (condition.getPageSize() > 0x0)
            //    pageSize = condition.getPageSize();

            //IPage<EhsTaskInfo> page = new Page<>(pageNum, pageSize);
            //IPage<EhsTaskInfo> pageResult = repository.selectPage(page, wrapper);

            List<EhsTaskInfo> ens = taskInfoRepository.selectList(wrapper);

            //6.获取查询结果，暂时不分页
            //result.setTotal(pageResult.getTotal());
            //result.setPages(pageResult.getPages());
            //List<EhsTaskInfo> ens = pageResult.getRecords();
            //if (CollectionUtils.isNotEmpty(ens)) {
            //    result.setItems(EhsTaskInfoMapper.MAPPER.toDtoList(ens));
            //}
            //
            //return result;

            if (CollectionUtils.isNotEmpty(ens)) {
                List<TaskInfoDto> result = new ArrayList<>();

                for (EhsTaskInfo en : ens) {
                    //dto中需要检查表ID集合时使用entityToDto方法，不需要时使用toDto方法
                    result.add(EhsTaskInfoMapper.MAPPER.toDto(en));
                }

                return result;
            }
        }

        return null;
    }

    /**
     * 查询指定任务的分组和任务项
     * <p>
     * 查询指定任务的所有分组和每个分组中的任务项集合；按照任务分组--任务项层级关系显示指定任务；
     *
     * @param id 任务ID
     * @return List<TaskGroupItemsDto>
     * @author QuCheng Tech
     * @since 2024/11/18
     */
    public List<TaskGroupItemsDto> getTaskGroupAndItems(String id) {
        if (StringUtils.isBlank(id)) return null;

        List<TaskGroupItemsDto> result = new ArrayList<>();

        //获取指定任务的任务分组
        List<TaskGroupInfoDto> groups = taskGroupService.getTaskGroups(id);
        if (CollectionUtils.isNotEmpty(groups)) {
            for (TaskGroupInfoDto group : groups) {
                TaskGroupItemsDto groupItems = new TaskGroupItemsDto();
                groupItems.setGroup(group);
                groupItems.setItems(new ArrayList<>());
                //获取指定任务分组下的任务项集合
                List<TaskItemInfoDto> items = taskItemService.getItemsByGroupId(group.getGroupid());
                if (CollectionUtils.isNotEmpty(items)) {
                    groupItems.setItems(items);
                }
                result.add(groupItems);
            }
        }

        return result;
    }
}
